package ft.xpf.impl;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.input.DataFormat;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import ft.jsf.util.StrUtil;
import ft.jsf.util.U;
//import ft.xpf.util.StringUtil;
import ft.xpf.util.XmlParseUtil;
import ft.xpf.util.JsonParseUtil;

public class DeskXmlParseFormatController extends DeskXmlParseFormatBaseRunner
{
	public TextArea txt1;
	public TextArea txt2;
	public Button btnFormatPretty;
	public Button btnFormatCompact;
	
	public TextField txtXpath;
	public TextArea txtSelectResult;
	public Button btnSelectSingle;
	public Button btnDecode;
	
	public ChoiceBox<String> ddlType;
	
	public Button btnClear1;
	public Button btnClear2;
	public Button btnPaste1;
	public Button btnPaste2;
	public Button btnCopyTo1;
	public Button btnCopyTo2;
	
	public void initialize()
	{
		btnFormatPretty.setOnAction(new EventHandler<ActionEvent>(){
			public void handle(ActionEvent arg0)
			{
				setFormatDirection(C._FORMAT_DIRECTION_PRETTY);
				startButton(txt1, txt2);
			}
		});
		
		btnFormatCompact.setOnAction(new EventHandler<ActionEvent>(){
			public void handle(ActionEvent arg0)
			{
				setFormatDirection(C._FORMAT_DIRECTION_COMPACT);
				startButton(txt2, txt1);
			}
		});
		
		btnSelectSingle.setOnAction(new EventHandler<ActionEvent>(){
			public void handle(ActionEvent arg0){
				String a = txt1.getText();
				String b = txtXpath.getText();
				String x = "";
				
				autoSetDDLType(a);
				
				String type = getDDLType();
				
				if(a!=null && a.length()>0 && b!=null && b.length()>0 )
				{
					try
					{
						if(C._FORMAT_TYPE_XML.equals(type))
						{
//							x = XmlParseUtil.xmlSelectSingle(a,b);
							x = XmlParseUtil.xmlSelectSingleA(a, b, null);
						}
						else if(C._FORMAT_TYPE_JSON.equals(type))
						{
							x = JsonParseUtil.jsonSelectSingle(a, b);
						}
					}
					catch(Exception e)
					{
						x = "有错误发生：\n" + e.getMessage();
					}
				}
				
				if(x!=null && x.length()>0)
				{
					txtSelectResult.setText(x);
				}
				else
				{
					txtSelectResult.clear();
				}
			}
		});
		
		{
			// ChoiceBox 增加子项
			ObservableList<String> lst = 
					FXCollections.observableArrayList(C._FORMAT_TYPE_XML, C._FORMAT_TYPE_JSON);
			ddlType.setItems(lst);
			
			//设置默认选中值
			ddlType.setValue(C._FORMAT_TYPE_XML);
		}
		
		// 清除
		btnClear1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				txt1.clear();
			}
		});
		
		// 清除
		btnClear2.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				txt2.clear();
			}
		});
		
		// 从剪贴板粘贴
		btnPaste1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				String str = getStringFromClipBoard();
				if(str!=null && str.length()>0)
				{
					txt1.setText(str);
				}
			}
		});
		
		// 从剪贴板粘贴
		btnPaste2.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				String str = getStringFromClipBoard();
				if(str!=null && str.length()>0)
				{
					txt2.setText(str);
				}
			}
		});
		
		// 复制到剪贴板
		btnCopyTo1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				String str = txt1.getText();
				if(str!=null && str.length()>0)
				{
					setStringToClipboard(str);
				}
			}
		});
		
		// 复制到剪贴板
		btnCopyTo2.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				String str = txt2.getText();
				if(str!=null && str.length()>0)
				{
					setStringToClipboard(str);
				}
			}
		});
		
		setDragDropEvents();
//		setToolTips();
		setToolTipsAlt();
	}
	
	/**
	 * 设置 txt1 控件拖放
	 */
	private void setDragDropEvents()
	{
		txt1.setOnDragOver(new EventHandler<DragEvent>()
		{
			@Override
			public void handle(DragEvent event)
			{
				event.acceptTransferModes(TransferMode.ANY);
			}
		});
		
		txt1.setOnDragDropped(new EventHandler<DragEvent>()
		{
			@Override
			public void handle(DragEvent event)
			{
				setFormatDirection(C._FORMAT_DIRECTION_PRETTY);
				startDrop(event, txt1, txt2);
			}
		});
		
		txt2.setOnDragOver(new EventHandler<DragEvent>()
		{
			@Override
			public void handle(DragEvent event)
			{
				event.acceptTransferModes(TransferMode.ANY);
			}
		});
		
		txt2.setOnDragDropped(new EventHandler<DragEvent>()
		{
			@Override
			public void handle(DragEvent event)
			{
				setFormatDirection(C._FORMAT_DIRECTION_COMPACT);
				startDrop(event, txt2, txt1);
			}
		});
	}
	
	/**
	 * 从界面取下拉框当前选中的值
	 * @return
	 */
	public String getDDLType()
	{
		String ret = "";
		Object ob = ddlType.getValue();
		if(ob!=null && ob instanceof java.lang.String)
		{
			ret = (java.lang.String)ob;
		}
		return ret;
	}
	
	/**
	 * 调用 guessType(String) 并将结果反馈到界面 ddlType 上。
	 * @param xml
	 */
	public void autoSetDDLType(String xml)
	{
		String guess = guessType(xml);
		
		if(guess!=null && guess.length()>0)
		{
			ddlType.setValue(guess);
		}
	}
	
	/**
	 * 手动强行设置 DDL Type 控件。
	 * @param type
	 */
	private void setDDLType(String type)
	{
		if(ddlType!=null && type!=null && type.length()>0)
		{
			ddlType.setValue(type);
		}
	}
	
	/**
	 * 按钮调用
	 */
	private void startButton(TextArea iptTxtA, TextArea iptTxtB)
	{
		String a = iptTxtA.getText();
		
		if(a!=null  && a.length()>0)
		{
			setStrTxt1(a);
			
			startRun();
			String b = "";
			b = getStrTxt2();
			
			if(b!=null && b.length()>0)
			{
				iptTxtB.setText(b);
				
				String type = null;
				type = getFormatType();
				setDDLType(type);
			}
		}
	}
	
	/**
	 * 拖放调用<br />
	 * txt1 和 txt2 的 drop 都会调用这里
	 * 
	 * @param event 拖放事件
	 * @param iptTxtA 原文本框（被放进的是哪个 TextArea ）
	 * @param iptTxtB 目标文本框（拖放的另一个 TextArea ）
	 */
	private void startDrop(DragEvent event , TextArea iptTxtA, TextArea iptTxtB)
	{
		Dragboard dd = event.getDragboard();
		Set<DataFormat> ds = dd.getContentTypes();
		if(ds.contains(DataFormat.FILES))
		{
			List<File> fls = dd.getFiles();
			if(fls!=null && fls.size()>0)
			{
				File fl = fls.get(0); // 只取第一个文件
				String fsname = null;
				try
				{
					fsname = fl.getCanonicalPath();
				}
				catch(Exception e)
				{
					// 有错误发生
					if(txtSelectResult!=null)
					{
						txtSelectResult.setText("文件路径不存在或者文件系统有错误发生。");
					}
				}
				
				if(fsname!=null && fsname.length()>0)
				{
					txtSelectResult.setText("获得文件路径：" + fsname);
					setStrPath1(fsname);
					
					String _src_str = U.getStrFromFilePath(fsname);
					String _dst_str = null;
					
					setStrTxt1(_src_str);
					startRun();
					_dst_str = getStrTxt2();
					
					String type = getFormatType();
					
					// 将结果写入文件系统
					if(_dst_str!=null && _dst_str.length()>0 )
					{
						String file_path2 = null;
						String file_name2 = null;
						if(type!=null && type.length()>0)
						{
							file_name2 = type + "_" + StrUtil.getTs14();
						}
						else
						{
							file_name2 = StrUtil.getTs14();
						}
						
						file_path2 = StrUtil.fixSuffix(fsname, file_name2);
						if(file_path2!=null && file_path2.length()>0)
						{
							// 文件输出
							FileOutputStream fos = null;
							try
							{
								fos = new FileOutputStream(file_path2);
								U.putStrToOs(_dst_str, fos, C._ENCODING_UTF8);
							}
							catch(Exception e)
							{
								System.out.print("写文件有错误发生：");
								System.out.println(e.getMessage());
								e.printStackTrace();
							}
							
							if(fos!=null)
							{
								try
								{
									fos.close();
								}
								catch(Exception e)
								{
								}
								fos = null;
							}
						}
					}
				}
			}
		}
		else if(ds.contains(DataFormat.PLAIN_TEXT))
		{
			// 没有文件，直接是文字
			String out_msg = dd.getString();
			if(out_msg!=null && out_msg.length()>0)
			{
				// 放入原文本框
				iptTxtA.setText(out_msg);
				startButton(iptTxtA, iptTxtB);
			}
		}
		else
		{
			// 其他情况，忽略
		}
	}
	
	/**
	 * 通过反射机制为控件设置 Tooltip 文本
	 */
	private void setToolTipsAlt()
	{
		Class<? extends DeskXmlParseFormatController> clz = this.getClass();
		Field[] fds = null;
		fds = clz.getFields();
		
		Map<String,String> hmTtp = C.getHmTtp();
		
		if(fds!=null && fds.length>0)
		{
			for(int i=0; i<fds.length; i++)
			{
				String fdName = null;
				Object obz = null;
				javafx.scene.control.Control ctz = null;
				
				Field fd = fds[i];
				fdName = fd.getName();
				
				if(fdName!=null && fdName.length()>0 && hmTtp.containsKey(fdName) )
				{
					try
					{
						obz = fd.get(this);
					}
					catch(Exception e)
					{
						System.out.println("取 field 有错误发生");
						System.out.println(e.getMessage());
						e.printStackTrace();
					}
					
					if(obz != null &&  obz instanceof javafx.scene.control.Control)
					{
						ctz = (javafx.scene.control.Control)obz;
						
						if(ctz!=null)
						{
							String ttTxt = hmTtp.get(fdName);
							Tooltip tt = new Tooltip();
							tt.setText( ttTxt );
							ctz.setTooltip(tt);
						}
					}
				}
			}
		}
	}
}
